package com.rainsoftware.LicenseSystem.services;

import com.rainsoftware.LicenseSystem.models.entity.KeyPair;
import com.rainsoftware.LicenseSystem.models.entity.LicenseKey;
import com.rainsoftware.LicenseSystem.models.entity.Product;
import com.rainsoftware.LicenseSystem.utils.RSAKeyGenerator;
import com.rainsoftware.LicenseSystem.utils.StandardResponse;
import gaarason.database.contract.eloquent.Record;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.time.LocalDateTime;

@Service
public class ActivationService {

    @Autowired
    private LicenseKey.Model licenseKeyModel;

    @Autowired
    private Product.Model productModel;

    @Autowired
    private KeyPair.Model keypairModel;

    public StandardResponse activateLicense(String licenseKey, String productSdkKey, String machine) {
        // 查找产品记录
        Record<Product, Integer> productRecord = productModel.newQuery().where("api_id", productSdkKey).first();
        if (productRecord == null) {
            return new StandardResponse(false, HttpStatus.NOT_FOUND, "产品不存在", null);
        }

        // 查找激活码记录
        Record<LicenseKey, Integer> licenseKeyRecord = licenseKeyModel.newQuery()
                .where("license_key", licenseKey)
                .where("product_id", productRecord.getEntity().getId())
                .first();
        if (licenseKeyRecord == null) {
            return new StandardResponse(false, HttpStatus.NOT_FOUND, "激活码不存在", null);
        }

        if (licenseKeyRecord.getEntity().getActivated()) {
            return new StandardResponse(false, HttpStatus.INTERNAL_SERVER_ERROR, "密钥已经激活，请求无效", null);
        }

        // 获取密钥对
        Record<KeyPair, Integer> keyPairRecord = keypairModel.newQuery().where("developer_id", licenseKeyRecord.getEntity().getDeveloperId()).first();
        if (keyPairRecord == null) {
            return new StandardResponse(false, HttpStatus.INTERNAL_SERVER_ERROR, "密钥错误 (1)，请联系软件开发者", null);
        }

        try {
            PublicKey publicKey = RSAKeyGenerator.getPublicKeyFromBase64(keyPairRecord.getEntity().getPubKey());

            // 创建签名内容
            JSONObject jsonObject = new JSONObject()
                    .put("uuid", machine)
                    .put("product", productRecord.getEntity().getName())
                    .put("activated_at", System.currentTimeMillis())
                    .put("duration", licenseKeyRecord.getEntity().getDuration())
                    .put("license_key", licenseKeyRecord.getEntity().getLicenseKey());

            try {
                // 使用公钥加密
                String encrypted = RSAKeyGenerator.encryptWithPublicKey(jsonObject.toString(), publicKey);

                // 更新数据库
                licenseKeyRecord.getEntity().setActivated(true);
                licenseKeyRecord.getEntity().setMachine(machine);
                licenseKeyRecord.getEntity().setActivatedAt(LocalDateTime.now());
                licenseKeyRecord.save();

                // 激活的时候更新产品激活记录
                productRecord.getEntity().setActivationCount(
                        productRecord.getEntity().getActivationCount() + 1
                );
                productRecord.save();

                return new StandardResponse(true, HttpStatus.OK, "",
                        new JSONObject().put("license", encrypted));

            } catch (Exception e) {
                return new StandardResponse(false, HttpStatus.INTERNAL_SERVER_ERROR, "密钥错误 (2)，请联系软件开发者", null);
            }
        } catch (InvalidKeySpecException e) {
            return new StandardResponse(false, HttpStatus.INTERNAL_SERVER_ERROR, "密钥错误 (3)，请联系软件开发者", null);
        } catch (NoSuchAlgorithmException e) {
            return new StandardResponse(false, HttpStatus.INTERNAL_SERVER_ERROR, "内部服务器错误", null);
        }
    }
}